#include "gcs.h"

#include <QApplication>
#include <QFile>
#include <QDateTime>

GCS::GCS(QObject *parent) :
    QObject(parent)
{
    // Initialize member variables
    _fileLoggingRunning = true;
    _fileLogLocation = QApplication::applicationDirPath();

    StartFileLogging();
}


/*
  SetFileLogLocation

  Desc - Sets the location where log files are saved
  */
void GCS::SetFileLogLocation(QString newFileLogLocation)
{
    bool prevIsFileLoggingValue;

    prevIsFileLoggingValue = isFileLoggingRunning();

    if(prevIsFileLoggingValue){
        toggleFileLogging();
    }

    _fileLogLocation = newFileLogLocation;

    if(prevIsFileLoggingValue){
        toggleFileLogging();
    }
}

/*
  GetFileLogLocation

  Desc - Gets the location where log files are saved
  */
QString GCS::GetFileLogLocation(){
    return _fileLogLocation;
}

/*
  StartFileLogging

  Desc - Sets up and starts the file log writing loop
  */
void GCS::StartFileLogging()
{
    // Work out the name of the file log
    _fileLogName = getCurrentDateTimeAsString(false);

    // Set up connections between the GCS and the file logging timer
    connect(&_fileLoggingTimer, SIGNAL(timeout()), this, SLOT(UpdateFileLog()));

    // Start the file logging timer
    // NOTE - 20ms = 50Hz
    _fileLoggingTimer.start(20);
}

/*
  StopFileLogging

  Desc - Stops the file log writing loop
  */
void GCS::StopFileLogging()
{
    // Stop the file logging timer
    _fileLoggingTimer.stop();

    // Remove connections between the GCS and the file logging timer
    disconnect(&_fileLoggingTimer, SIGNAL(timeout()), this, SLOT(UpdateFileLog()));
}

/*
  ChangeFileLoggingUpdateFrequency

  Desc - Changes the rate at which the file log is written to. Stops the 
  		 file log timer, and restarts it with the passed 
  		 update rate value (in ms)
  */
void GCS::ChangeFileLoggingUpdateFrequency(int updateRate)
{

}

QString GCS::getCurrentDateTimeAsString(bool withMilliseconds, QString valueSeperator)
{
    QString dateTimeString = "";

    // See http://doc.qt.nokia.com/latest/qdatetime.html#toString for details on format

    dateTimeString = QDateTime::currentDateTime().toString("yyyyMMdd");
    dateTimeString += valueSeperator;
    dateTimeString += QDateTime::currentDateTime().toString("hhmmss");

    if(withMilliseconds){
        dateTimeString += valueSeperator;
        dateTimeString += QDateTime::currentDateTime().toString("zzz");
    }

    return dateTimeString;
}

/*
  isFileLoggingRunning

  Desc - Indicates if file logging is currently running in the GCS object
  */
bool GCS::isFileLoggingRunning()
{
    return _fileLoggingRunning;
}

/*
  toggleFileLogging

  Desc - Turns file logging either on or off, depending on its current state
         (like a lightswitch)
  */
void GCS::toggleFileLogging()
{
    _fileLoggingRunning = !_fileLoggingRunning;

    if(!_fileLoggingRunning){
        StopFileLogging();
    } else {
        StartFileLogging();
    }
}

/*
  SendRollGainsToArduino

  Desc - Sends the roll gain values to the Arduino device
  */
void GCS::SendRollGainsToArduino()
{

}

/*
  SendPitchGainsToArduino

  Desc - Sends the pitch gain values to the Arduino device
  */
void GCS::SendPitchGainsToArduino()
{

}

/*
  SendYawGainsToArduino

  Desc - Sends the yaw gain values to the Arduino device
  */
void GCS::SendYawGainsToArduino()
{

}


/*
  DEBUG_DoSevenSegDataTest

  Desc - Performs the Seven Segment display data test
  */
void GCS::DEBUG_DoSevenSegDataTest()
{

}

/*
  DEBUG_DoSevenSegRateTest

  Desc - Performs the Seven Segment display rate test
  */
void GCS::DEBUG_DoSevenSegRateTest()
{

}

/*
  DEBUG_DoAHDataTest

  Desc - Performs the AH data test
  */
void GCS::DEBUG_DoAHDataTest()
{

}

/*
  DEBUG_DoBlackAndWhiteBoxTests

  Desc - Performs the code black and white box tests
  */
void GCS::DEBUG_DoBlackAndWhiteBoxTests()
{

}



// slots

/*
  SendVICONValuesToArduino

  Desc - Reacts to a VICON "valuesUpdated" signal, and sends 
  		 values on to the Arduino
  */
void GCS::SendVICONValuesToArduino()
{

}

/*
  ProcessUpdatedAeroQuadModel

  Desc - Reacts to a AeroQuad "valuesUpdated" signal. Updates the seven segment
  		 displays, and writes to the log file if enabled.
  */
void GCS::ProcessUpdatedAeroQuadModel()
{

}

/*
  UpdateFileLog

  Desc - Writes to the log file, and checks for file size
  */
void GCS::UpdateFileLog()
{
    qint64 fileSize; // in bytes
    float fileSizeMB;
    QFile *logFile;
    QString logEntry;
    bool logFileIsNew;

    // Open the log file
    QString _fileLogPath = _fileLogLocation + "/OSIQLog_" + _fileLogName + ".csv";

    logFile = new QFile(_fileLogPath);

    logFileIsNew = !logFile->exists();

    if(logFileIsNew){
        emit newLogFileCreated();
    }

    logFile->open(QFile::Append);

    if(logFileIsNew){
        logEntry = "Date (YYYYMMDD),Time (HHMMSS),Milliseconds,X,Y,Z,Vx,Vy,Vz,R,P,Y,Vr,Vp,Vy,Pr,Ir,Dr,Pp,Ip,Dp,Py,Iy,Dy\n";

        logFile->write(logEntry.toAscii());
    }

    // Write the data to the log file
    logEntry = getCurrentDateTimeAsString(true, ",") + "," + _aeroQuadModel.toString() + "\n";

    logFile->write(logEntry.toAscii());

    // Check the size of the log file to see if a new one needs to be started
    fileSize = logFile->size();
    fileSizeMB = ((fileSize / 1024) / 1024);

    if(fileSizeMB == 4){
        _fileLogName = getCurrentDateTimeAsString(false);
    }

    logFile->close();

    delete logFile;
}

